
// ===============================================================================================================
// -*- C++ -*-
//
// FmodSystem.hpp - FMOD sound system helper classes and functions.
//
// Copyright (c) 2011 Guilherme R. Lampert
// guilherme.ronaldo.lampert@gmail.com
//
// This code is licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// above is included in the resulting source code.
//
// ===============================================================================================================

#ifndef __FMOD_SYSTEM_HPP__
#define __FMOD_SYSTEM_HPP__

/*
 * The FMOD library is copyright of Firelight Technologies Ltd.
 * This classes only provide a C++ interface to their API.
 */
#include <Fmod.hpp>

// Local includes
#include <Common.hpp>
#include <RefPtr.hpp>
#include <ReferenceCountable.hpp>

namespace FMOD {

///
/// SoundSystem -- Initializes an terminates the FMOD sound system.
/// The SoundSystem class is a singleton.
///
class SoundSystem {

public:

	/// Init the FMOD library.
	static bool Initialize(int mixRate, int maxSoftwareChannels, unsigned int Flags);

	/// Close the FMOD library and do a proper cleanup.
	static void Shutdown(void);

	/// Checks if the sound system is in a good state.
	static bool Good(void);

	/// Load a sound sample from a file. Will return a null pointer on failure.
	static class Sound * CreateSoundFromFile(const std::string & fileName);

private:

	static bool initalized;

	 SoundSystem(void) { /**/ };
	~SoundSystem(void) { /**/ };
};

///
/// Sound -- FMOD sound object. Represents a sound sample loaded from a file.
/// See the FMOD library documentation for further information.
///
class Sound : public ReferenceCountable {

	friend class SoundSystem;

public:

	// Public Interface:

	bool IsPlaying(void) const;

	void SetVolume(int volume);

	void SetVolumeAbsolute(int volume);

	void Play(void);

	void Stop(void);

	inline bool Fail(void) const { return (sample == 0); };

	inline int GetChannel(void) const { return (sampleChannel); };

	inline FSOUND_SAMPLE * GetSample(void) const { return (sample); };

	// ReferenceCountable Methods:

	virtual unsigned long AddRef(void) const;
	virtual unsigned long Release(void) const;
	virtual unsigned long ReferenceCount(void) const;

private:

	Sound(void) { /**/ };
	Sound(const std::string & fileName);

	~Sound(void);

	int sampleChannel;
	FSOUND_SAMPLE * sample;
};

///
/// Reference countable sound pointer type.
///
typedef RefPtr<Sound> SoundPtr;

}; // namespace FMOD {}

#endif // __FMOD_SYSTEM_HPP__